/*
 * Copyright 2012-2014 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.jqd.framework.core.hessian.biz.action.support.annotation;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.jqd.framework.core.exception.BusinessServiceException;
import com.jqd.framework.core.hessian.biz.action.ActionHandlerAdapter;
import com.jqd.framework.core.hessian.biz.action.support.ActionMethodInvoker;
import com.jqd.framework.core.hessian.biz.action.support.ActionMethodResolver;
import com.jqd.framework.core.hessian.biz.action.support.JdkReflectionMethodInvoker;
import com.jqd.framework.core.hessian.exception.NoHandlingMethodFoundExeception;
import com.jqd.framework.core.hessian.model.ServiceRequest;
import com.jqd.framework.core.hessian.model.ServiceResponse;

/**
 * 
 * TODO
 * 
 * @author liaozhicheng.cn@gmail.com
 * @date 2012-6-11
 * @since 1.0
 */
public class AnnotationActionHandlerAdapter implements ActionHandlerAdapter {
	
	private static final Log log = LogFactory.getLog(AnnotationActionHandlerAdapter.class);
	
	
	@Override
	public boolean supports(ServiceRequest serviceRequest, Object handler) {
		return handler.getClass().isAnnotationPresent(ActionHandler.class);
	}
	
	
	@Override
	public ServiceResponse handle(ServiceRequest serviceRequest, Object handler)
			throws BusinessServiceException {
		String actionId = serviceRequest.getRequestedActionID();
		
		ActionMethodResolver methodResolver = AnnotationMethodResolver.getInstance();
		Method method = methodResolver.resolve(handler, actionId);
		
		ActionMethodInvoker methodInvoker = new JdkReflectionMethodInvoker(method);
		return methodInvoker.invoke(method, handler, serviceRequest);
	}
	
	static class AnnotationMethodResolver implements ActionMethodResolver {
		
		private static class AnnotationMethodResolverInstanceHolder {
			
			private static final AnnotationMethodResolver instance = new AnnotationMethodResolver();
		}
		
		
		public static AnnotationMethodResolver getInstance() {
			return AnnotationMethodResolverInstanceHolder.instance;
		}
		
		
		// TODO list
		// 1.考虑加入缓存查找，这样就不需要每次解析都要进行循环对比
		
		@Override
		public Method resolve(Object handler, String actionId) throws BusinessServiceException {
			Method[] methods = handler.getClass().getMethods();
			
			for (Method method : methods) {
				if (method.isAnnotationPresent(HandleRquest.class)) {
					HandleRquest hr = method.getAnnotation(HandleRquest.class);
					if (actionId.equals(hr.value())) {
						if (log.isDebugEnabled()) {
							log.debug(new StringBuilder().append("==== mapping [").append(actionId)
									.append("] --> ").append(handler.getClass().getName())
									.append("#").append(method.getName()).append("() ====")
									.toString());
						}
						return method;
					}
				}
			}
			throw new NoHandlingMethodFoundExeception(actionId, handler);
		}
	}
	
}
